import { Vec3, Mat4, Vec4 } from '../common/math/TSM'
import { TypedArrayList } from '../common/container/TypedArrayList'
import { EAxisType } from '../common/math/MathHelper'
import { GLMeshBuilder } from '../webgl/WebGLMesh'
export class CoordSystem {
    public viewport: number[] = []; // 当前坐标系被绘制在哪个视口中
    public axis: Vec3; // 当前坐标系绕哪个轴旋转
    public angle: number; // 当前坐标系的旋转的角度(不是弧度！)
    public pos: Vec3; // 当前坐标系的位置，如果是多视口渲染的话，就为[0,0,0]
    public isDrawAxis: boolean; // 是否绘制旋转轴
    public isD3D: boolean; // 是否绘制为D3D左手系

    public constructor (viewport: number[], pos: Vec3 = Vec3.zero, axis: Vec3 = Vec3.up, angle: number = 0, isDrawAxis: boolean = false, isD3D: boolean = false) {
      this.viewport = viewport
      this.angle = angle
      this.axis = axis
      this.pos = pos
      this.isDrawAxis = isDrawAxis
      this.isD3D = isD3D
    }
}

export class DrawHelper {
    public static defaultHitCollor: Vec4 = new Vec4([1, 1, 0]);

    public static getCirclePointsOnXYPlane (pts: TypedArrayList<Float32Array>, radius: number, segment: number = 32): void {
      pts.clear()
      const step: number = Math.PI / segment
      let ang: number = 0
      for (let i: number = 0; i <= segment; i++) {
        ang = i * step
        pts.push(Math.cos(ang))
        pts.push(Math.sin(ang))
        pts.push(0.0)
      }
    }

    public static drawFullCoordSystem (builder: GLMeshBuilder, mat: Mat4, len: number = 1, rotateAxis: Vec3 | null = null): void {
      builder.gl.lineWidth(5) // 用5个像素大小的直径绘制线段，但目前仅Safari浏览器实现
      builder.gl.disable(builder.gl.DEPTH_TEST) // 关闭帧缓存深度测试
      builder.begin(builder.gl.LINES)
      // 正x轴

      builder.color(1.0, 0.0, 0.0).vertex(0.0, 0.0, 0.0)
      builder.color(1.0, 0.0, 0.0).vertex(len, 0, 0)

      // 负x轴

      builder.color(1.0, 0.0, 0.0).vertex(0.0, 0.0, 0.0)
      builder.color(1.0, 0.0, 0.0).vertex(-len, 0, 0)

      // 正y轴

      builder.color(0.0, 1.0, 0.0).vertex(0.0, 0.0, 0.0)
      builder.color(0.0, 1.0, 0.0).vertex(0.0, len, 0.0)

      // 负y轴

      builder.color(0.0, 1.0, 0.0).vertex(0.0, 0.0, 0.0)
      builder.color(0.0, 1.0, 0.0).vertex(0.0, -len, 0.0)

      // 正z轴

      builder.color(0.0, 0.0, 1.0).vertex(0.0, 0.0, 0.0)
      builder.color(0.0, 0.0, 1.0).vertex(0.0, 0.0, len)

      // 负z轴

      builder.color(0.0, 0.0, 1.0).vertex(0.0, 0.0, 0.0)
      builder.color(0.0, 0.0, 1.0).vertex(0.0, 0.0, -len)

      if (rotateAxis !== null) {
        // 如果要绘制旋转轴，则绘制出来
        const scale: Vec3 = rotateAxis.scale(len)
        builder.color(0.0, 0.0, 0.0).vertex(0, 0, 0)
        builder.color(0.0, 0.0, 0.0).vertex(scale.x, scale.y, scale.z)
      }
      builder.end(mat) // 将渲染数据提交给GPU进行渲染
      builder.gl.lineWidth(1) // 恢复线宽为1个像素
      builder.gl.enable(builder.gl.DEPTH_TEST) // 恢复开始帧缓存深度测试
    }

    public static drawCoordSystem (builder: GLMeshBuilder, mat: Mat4, hitAxis: EAxisType, len: number = 5, rotateAxis: Vec3 | null = null, isLeftHandness: boolean = false): void {
      builder.gl.lineWidth(5)
      builder.gl.disable(builder.gl.DEPTH_TEST)
      builder.begin(builder.gl.LINES)
      if (hitAxis === EAxisType.XAXIS) {
        builder.color(DrawHelper.defaultHitCollor.r, DrawHelper.defaultHitCollor.g, DrawHelper.defaultHitCollor.b).vertex(0.0, 0.0, 0.0)
        builder.color(DrawHelper.defaultHitCollor.r, DrawHelper.defaultHitCollor.g, DrawHelper.defaultHitCollor.b).vertex(len, 0, 0)
      } else {
        builder.color(1.0, 0.0, 0.0).vertex(0.0, 0.0, 0.0)
        builder.color(1.0, 0.0, 0.0).vertex(len, 0, 0)
      }

      if (hitAxis === EAxisType.YAXIS) {
        builder.color(DrawHelper.defaultHitCollor.r, DrawHelper.defaultHitCollor.g, DrawHelper.defaultHitCollor.b).vertex(0.0, 0.0, 0.0)
        builder.color(DrawHelper.defaultHitCollor.r, DrawHelper.defaultHitCollor.g, DrawHelper.defaultHitCollor.b).vertex(0, len, 0)
      } else {
        builder.color(0.0, 1.0, 0.0).vertex(0.0, 0.0, 0.0)
        builder.color(0.0, 1.0, 0.0).vertex(0.0, len, 0.0)
      }

      if (hitAxis === EAxisType.ZAXIS) {
        builder.color(DrawHelper.defaultHitCollor.r, DrawHelper.defaultHitCollor.g, DrawHelper.defaultHitCollor.b).vertex(0.0, 0.0, 0.0)
        if (isLeftHandness === true) {
          builder.color(DrawHelper.defaultHitCollor.r, DrawHelper.defaultHitCollor.g, DrawHelper.defaultHitCollor.b).vertex(0, 0, -len)
        } else {
          builder.color(DrawHelper.defaultHitCollor.r, DrawHelper.defaultHitCollor.g, DrawHelper.defaultHitCollor.b).vertex(0, 0, len)
        }
      } else {
        builder.color(0.0, 0.0, 1.0).vertex(0.0, 0.0, 0.0)
        if (isLeftHandness === true) {
          builder.color(0.0, 0.0, 1.0).vertex(0.0, 0.0, -len)
        } else {
          builder.color(0.0, 0.0, 1.0).vertex(0.0, 0.0, len)
        }
      }

      if (rotateAxis !== null) {
        const scale: Vec3 = rotateAxis.scale(len)
        builder.color(0.0, 0.0, 0).vertex(0, 0, 0)
        if (isLeftHandness === true) {
          builder.color(0.0, 0.0, 0.0).vertex(scale.x, scale.y, -scale.z)
        } else {
          builder.color(0.0, 0.0, 0.0).vertex(scale.x, scale.y, scale.z)
        }
      }

      builder.end(mat)
      builder.gl.lineWidth(1)
      builder.gl.enable(builder.gl.DEPTH_TEST)
    }

    /*
        /3--------/7  |
        / |       /   |
        /  |      /   |
        1---------5   |
        |  /2- - -|- -6
        | /       |  /
        |/        | /
        0---------4/
    */
    // 根据mins点（上图中的顶点2，左下后）和maxs（上图中的顶点5，右上前）点的坐标，使用参数指定的颜色绘制线框绑定盒，它是一个立方体
    // GLMeshBuilder的begin / end被调用了三次
    public static drawBoundBox (builder: GLMeshBuilder, mat: Mat4, mins: Vec3, maxs: Vec3, color: Vec4 = Vec4.red): void {
      builder.gl.disable(builder.gl.DEPTH_TEST)
      // 使用LINE_LOOP绘制底面，注意顶点顺序，逆时针方向，根据右手螺旋定则可知，法线朝外
      builder.begin(builder.gl.LINE_LOOP) // 使用的是LINE_LOOP图元绘制模式

      builder.color(color.r, color.g, color.b).vertex(mins.x, mins.y, mins.z) // 2  - - -
      builder.color(color.r, color.g, color.b).vertex(mins.x, mins.y, maxs.z) // 0  - - +
      builder.color(color.r, color.g, color.b).vertex(maxs.x, mins.y, maxs.z) // 4  + - +
      builder.color(color.r, color.g, color.b).vertex(maxs.x, mins.y, mins.z) // 6  + - -
      builder.end(mat)

      // 使用LINE_LOOP绘制顶面，注意顶点顺序，逆时针方向，根据右手螺旋定则可知，法线朝外
      builder.begin(builder.gl.LINE_LOOP) // 使用的是LINE_LOOP图元绘制模式

      builder.color(color.r, color.g, color.b).vertex(mins.x, maxs.y, mins.z) // 3  - + -
      builder.color(color.r, color.g, color.b).vertex(maxs.x, maxs.y, mins.z) // 7  + + -
      builder.color(color.r, color.g, color.b).vertex(maxs.x, maxs.y, maxs.z) // 5  + + +
      builder.color(color.r, color.g, color.b).vertex(mins.x, maxs.y, maxs.z) // 1  - + +
      builder.end(mat)

      // 使用LINES绘制
      builder.begin(builder.gl.LINES) // 使用的是LINES图元绘制模式

      builder.color(color.r, color.g, color.b).vertex(mins.x, mins.y, mins.z) // 2  - - -
      builder.color(color.r, color.g, color.b).vertex(mins.x, maxs.y, mins.z) // 3  - + -

      builder.color(color.r, color.g, color.b).vertex(mins.x, mins.y, maxs.z) // 0  - - +
      builder.color(color.r, color.g, color.b).vertex(mins.x, maxs.y, maxs.z) // 1  - + +

      builder.color(color.r, color.g, color.b).vertex(maxs.x, mins.y, maxs.z) // 4  + - +
      builder.color(color.r, color.g, color.b).vertex(maxs.x, maxs.y, maxs.z) // 5  + + +

      builder.color(color.r, color.g, color.b).vertex(maxs.x, mins.y, mins.z) // 6  + - -
      builder.color(color.r, color.g, color.b).vertex(maxs.x, maxs.y, mins.z) // 7  + + -
      builder.end(mat)

      builder.gl.enable(builder.gl.DEPTH_TEST)
    }

    public static drawWireFrameCubeBox (builder: GLMeshBuilder, mat: Mat4, halfLen: number = 0.2, color: Vec4 = Vec4.red): void {
      const mins: Vec3 = new Vec3([-halfLen, -halfLen, -halfLen])
      const maxs: Vec3 = new Vec3([halfLen, halfLen, halfLen])
      DrawHelper.drawBoundBox(builder, mat, mins, maxs, color)
    }

    /*
       /3--------/7  |
       / |       /   |
       /  |      /   |
       1---------5   |
       |  /2- - -|- -6
       | /       |  /
       |/        | /
       0---------4/
   */
    public static drawTextureCubeBox (builder: GLMeshBuilder, mat: Mat4, halfLen: number = 0.2, tc: number[] = [
      0, 0, 1, 0, 1, 1, 0, 1, // 前面
      0, 0, 1, 0, 1, 1, 0, 1, // 右面
      0, 0, 1, 0, 1, 1, 0, 1, // 后面
      0, 0, 1, 0, 1, 1, 0, 1, // 左面
      0, 0, 1, 0, 1, 1, 0, 1, // 上面
      0, 0, 1, 0, 1, 1, 0, 1 // 下面
    ]): void {
      // 前面
      builder.begin(builder.gl.TRIANGLE_FAN)
      builder.texcoord(tc[0], tc[1]).vertex(-halfLen, -halfLen, halfLen) // 0  - - +
      builder.texcoord(tc[2], tc[3]).vertex(halfLen, -halfLen, halfLen) // 4  + - +
      builder.texcoord(tc[4], tc[5]).vertex(halfLen, halfLen, halfLen) // 5  + + +
      builder.texcoord(tc[6], tc[7]).vertex(-halfLen, halfLen, halfLen) // 1  - + +
      builder.end(mat)
      // 右面
      builder.begin(builder.gl.TRIANGLE_FAN)
      builder.texcoord(tc[8], tc[9]).vertex(halfLen, -halfLen, halfLen) // 4  + - +
      builder.texcoord(tc[10], tc[11]).vertex(halfLen, -halfLen, -halfLen) // 6  + - -
      builder.texcoord(tc[12], tc[13]).vertex(halfLen, halfLen, -halfLen) // 7  + + -
      builder.texcoord(tc[14], tc[15]).vertex(halfLen, halfLen, halfLen) // 5  + + +
      builder.end(mat)
      // 后面
      builder.begin(builder.gl.TRIANGLE_FAN)
      builder.texcoord(tc[16], tc[17]).vertex(halfLen, -halfLen, -halfLen) // 6  + - -
      builder.texcoord(tc[18], tc[19]).vertex(-halfLen, -halfLen, -halfLen) // 2  - - -
      builder.texcoord(tc[20], tc[21]).vertex(-halfLen, halfLen, -halfLen) // 3  - + -
      builder.texcoord(tc[22], tc[23]).vertex(halfLen, halfLen, -halfLen) // 7  + + -
      builder.end(mat)
      // 左面
      builder.begin(builder.gl.TRIANGLE_FAN)
      builder.texcoord(tc[24], tc[25]).vertex(-halfLen, -halfLen, -halfLen) // 2  - - -
      builder.texcoord(tc[26], tc[27]).vertex(-halfLen, -halfLen, halfLen) // 0  - - +
      builder.texcoord(tc[28], tc[29]).vertex(-halfLen, halfLen, halfLen) // 1  - + +
      builder.texcoord(tc[30], tc[31]).vertex(-halfLen, halfLen, -halfLen) // 3  - + -
      builder.end(mat)
      // 上面
      builder.begin(builder.gl.TRIANGLE_FAN)
      builder.texcoord(tc[32], tc[33]).vertex(-halfLen, halfLen, halfLen) // 1  - + +
      builder.texcoord(tc[34], tc[35]).vertex(halfLen, halfLen, halfLen) // 5  + + +
      builder.texcoord(tc[36], tc[37]).vertex(halfLen, halfLen, -halfLen) // 7  + + -
      builder.texcoord(tc[38], tc[39]).vertex(-halfLen, halfLen, -halfLen) // 3  - + -
      builder.end(mat)
      // 下面
      builder.begin(builder.gl.TRIANGLE_FAN)
      builder.texcoord(tc[40], tc[41]).vertex(-halfLen, -halfLen, halfLen) // 0  - - +
      builder.texcoord(tc[42], tc[43]).vertex(-halfLen, -halfLen, -halfLen) // 2  - - -
      builder.texcoord(tc[44], tc[45]).vertex(halfLen, -halfLen, -halfLen) // 6  + - -
      builder.texcoord(tc[46], tc[47]).vertex(halfLen, -halfLen, halfLen) // 4  + - +
      builder.end(mat)
    }

    // 其中参数pts是Frustum.points返回的包含8个顶点的数组
    public static drawWireFrameFrustum (builder: GLMeshBuilder, mat: Mat4, pts: Vec3[], color: Vec4 = Vec4.red): void {
      builder.gl.disable(builder.gl.DEPTH_TEST)
      // 使用LINE_LOOP绘制近平面的四边形
      builder.begin(builder.gl.LINE_LOOP) // 使用的是LINE_LOOP图元绘制模式

      builder.color(color.r, color.g, color.b).vertex(pts[0].x, pts[0].y, pts[0].z) //
      builder.color(color.r, color.g, color.b).vertex(pts[1].x, pts[1].y, pts[1].z) //
      builder.color(color.r, color.g, color.b).vertex(pts[2].x, pts[2].y, pts[2].z) //
      builder.color(color.r, color.g, color.b).vertex(pts[3].x, pts[3].y, pts[3].z) //
      builder.end(mat)

      // 使用LINE_LOOP绘制远平面的四边形
      builder.begin(builder.gl.LINE_LOOP) // 使用的是LINE_LOOP图元绘制模式

      builder.color(color.r, color.g, color.b).vertex(pts[4].x, pts[4].y, pts[4].z) //
      builder.color(color.r, color.g, color.b).vertex(pts[5].x, pts[5].y, pts[5].z) //
      builder.color(color.r, color.g, color.b).vertex(pts[6].x, pts[6].y, pts[6].z) //
      builder.color(color.r, color.g, color.b).vertex(pts[7].x, pts[7].y, pts[7].z) //
      builder.end(mat)

      // 使用LINES绘制绘制近平面与远平面的四条边
      builder.begin(builder.gl.LINES) // 使用的是LINES图元绘制模式

      builder.color(color.r, color.g, color.b).vertex(pts[0].x, pts[0].y, pts[0].z) //
      builder.color(color.r, color.g, color.b).vertex(pts[4].x, pts[4].y, pts[4].z) //

      builder.color(color.r, color.g, color.b).vertex(pts[1].x, pts[1].y, pts[1].z) //
      builder.color(color.r, color.g, color.b).vertex(pts[5].x, pts[5].y, pts[5].z) //

      builder.color(color.r, color.g, color.b).vertex(pts[2].x, pts[2].y, pts[2].z) //
      builder.color(color.r, color.g, color.b).vertex(pts[6].x, pts[6].y, pts[6].z) //

      builder.color(color.r, color.g, color.b).vertex(pts[3].x, pts[3].y, pts[3].z) //
      builder.color(color.r, color.g, color.b).vertex(pts[7].x, pts[7].y, pts[7].z) //

      builder.end(mat)

      builder.gl.enable(builder.gl.DEPTH_TEST)
    }
}
